package com.efun.framework.beetlsql;

import com.alibaba.druid.pool.DruidDataSource;
import org.beetl.sql.core.Interceptor;
import org.beetl.sql.core.NameConversion;
import org.beetl.sql.core.db.DBStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * 用于管理拦截器，使其可以使用配置
 * @author kinven on 17-8-26.
 */
public class BeetlSqlBeanManager implements InitializingBean,ApplicationContextAware,BeanNameAware {

    private static final Logger LOG = LoggerFactory.getLogger(BeetlSqlBeanManager.class);

    ApplicationContext applicationContext;
    String beanName;
    String interceptorsName;
    String dbStyleName;
    String nameConversionName;
    String masteDataSourceName;
    String slaveDataSourceNames;

    private Set<Interceptor> interceptors = new LinkedHashSet<Interceptor>();
    private NameConversion nameConversion;
    private DBStyle dbStyle;
    private DruidDataSource masteDataSource;
    private Set<DruidDataSource> dataSourceSet = new LinkedHashSet<DruidDataSource>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    public void setInterceptorsName(String interceptors) {
        this.interceptorsName = interceptors;
    }

    public void setDbStyleName(String dbStyleName) {
        this.dbStyleName = dbStyleName;
    }

    public void setNameConversionName(String nameConversionName) {
        this.nameConversionName = nameConversionName;
    }

    public void setMasteDataSourceName(String masteDataSourceName) {
        this.masteDataSourceName = masteDataSourceName;
    }

    public void setSlaveDataSourceNames(String slaveDataSourceNames) {
        this.slaveDataSourceNames = slaveDataSourceNames;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        String[] names= StringUtils.tokenizeToStringArray(interceptorsName,",");
        for(String name : names) {
            Interceptor interceptor = applicationContext.getBean(name,Interceptor.class);
            if(interceptor == null){
                LOG.warn("Interceptor {} not found in BeetlSqlBeanManager,please check the config is correct.",name);
            } else {
                interceptors.add(interceptor);
            }
        }

        NameConversion nameConversion = applicationContext.getBean(nameConversionName,NameConversion.class);
        if(nameConversion == null){
            LOG.warn("nameConversion {} not found in BeetlSqlBeanManager,please check the config is correct.",nameConversionName);
        }
        DBStyle dbStyle = applicationContext.getBean(dbStyleName,DBStyle.class);
        if(dbStyle == null){
            LOG.warn("dbstyle {} not found in BeetlSqlBeanManager,please check the config is correct.",dbStyleName);
        }

        DruidDataSource dataSource = applicationContext.getBean(masteDataSourceName,DruidDataSource.class);
        if(dataSource == null){
            LOG.warn("datasource {} not found in BeetlSqlBeanManager,please check the config is correct.",masteDataSourceName);
        }

        String[] dsNames= StringUtils.tokenizeToStringArray(slaveDataSourceNames,",");
        for(String dsName : dsNames) {
            DruidDataSource druidDataSource = applicationContext.getBean(dsName,DruidDataSource.class);
            if(dataSource == null){
                LOG.warn("datasource {} not found in BeetlSqlBeanManager,please check the config is correct.",dsName);
            } else {
                dataSourceSet.add(dataSource);
            }
        }
    }

    public Interceptor[] getInterceptors(){
        return interceptors.toArray(new Interceptor[interceptors.size()]);
    }

    public NameConversion getNameConversion(){
        return this.nameConversion;
    }

    public DBStyle getDbStyle(){
        return this.dbStyle;
    }
}

